<?php
/**
 * Niushop商城系统 - 团队十年电商经验汇集巨献!
 * =========================================================
 * Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
 * ----------------------------------------------
 * 官方网址: https://www.niushop.com
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用。
 * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
 * =========================================================
 */

namespace app\model\system;

use app\model\message\SmsPackage;
use think\facade\Cache;
use app\model\BaseModel;

/**
 * 系统订单
 */
class SysOrder extends BaseModel
{
    private $pay_type = ['ONLINE_PAY' => '在线支付', 'OFFLINE_PAY' => '线下支付'];

    ///订单类型
    public $order_type = array(
        "group" => "套餐",
//        "site" => "站点",
        "sms" => "短信",
    );

    //订单状态
    public $order_status = array(
        0 => "待支付",
        2 => "支付待审核",
        3 => "审核拒绝",
        -1 => "已关闭",
        1 => "已完成",

    );

    /**
     * 获取支付方式
     */
    public function getPayType()
    {
        //获取订单基础的其他支付方式
        $pay_type = $this->pay_type;
        //获取当前所有在线支付方式
        $online_pay = event('PayType', []);
        if (!empty($online_pay)) {
            foreach ($online_pay as $k => $v) {
                $pay_type[$v['pay_type']] = $v['pay_type_name'];
            }
        }
        return $pay_type;
    }

    /**
     * 获取订单类型
     */
    public function getOrderType()
    {
        $order_type = $this->order_type;

        return $order_type;
    }

    /**
     * 获取订单状态
     */
    public function getOrderStatus()
    {
        $order_status = $this->order_status;

        return $order_status;
    }

    /**
     * 获取系统订单列表
     */
    public function getSysOrderPageList($condition, $page = 1, $page_size = PAGE_LIST_ROWS, $fields = '*', $order = 'create_time DESC')
    {
        $res = model('sys_order')->pageList($condition, $fields, $order, $page, $page_size);
        return $this->success($res);
    }
    /**
     * 获取系统订单列表
     */
    public function getSysOrderList($condition, $fields = '*', $order = 'create_time DESC')
    {
        $res = model('sys_order')->getList($condition, $fields, $order);
        return $this->success($res);
    }

    /**
     * 获取订单详情
     * @param $condtion
     * @param string $fields
     */
    public function getSysOrderInfo($condtion, $fields = '*', $alias = 'a', $join = [])
    {
        $res = model('sys_order')->getInfo($condtion, $fields, $alias, $join);
        return $this->success($res);
    }

    /**
     * 创建订单
     * @param $data
     * @return array
     */
    public function orderCreate($param)
    {
        model('sys_order')->startTrans();
        try {
            $buyer_info = $param['buyer_info'];
            //套餐信息
            $group_id = $param["group_id"] ?? 0;
            $group_num = $param["group_num"] ?? 0;
            $group_money = 0;
            $order_name = '';
            if ($group_id > 0 && $group_num > 0) {

                $order_type = "group";//套餐订单
                $sys_user_group_model = new SiteGroup();
                $group_info = $sys_user_group_model->getSiteGroupDetail([['group_id', '=', $group_id], ['status', '=', 1]], 'type, group_name, image, addon_array, unit, fee,sms_num');
                if (empty($group_info['data'])) {
                    return error();
                }
                $group_info = $group_info['data'];

                $data["group_id"] = $group_id;
                $data["group_name"] = $group_info['group_name'];
                $data['type'] = $group_info['type'];
                $data["group_image"] = $group_info['image'];
                $data["group_sms_num"] = $group_info['sms_num'];//免费赠送短信数
                $data["group_period_num"] = 1;
                $data["group_period_unit"] = $group_info['unit'];
                $data["group_period_price"] = $group_info['fee'];


                $group_money = $group_num * $group_info['fee'];
                $order_name = $group_info['group_name'];
            }
            $data["group_num"] = $group_num;

            $data["site_id"] = $param['site_id'];
            $data["site_name"] = $param['site_name'];
            //短信订单
            $sms_package_id = $param['sms_package_id'];
            $sms_package_num = $param['sms_package_num'];
            $sms_money = 0;
            //有效的短信套餐订单
            if ($sms_package_id > 0 && $sms_package_num > 0) {
                $order_type = 'sms';
                $sms_package_model = new SmsPackage();
                $sms_package_condition = array(
                    ['package_id', '=', $sms_package_id],
                    ['status', '=', 1]
                );
                $sms_package_result = $sms_package_model->getSmsPackageInfo($sms_package_condition, "sms_name, sms_image, sms_money, sms_num");
                $sms_package_info = $sms_package_result["data"];
                if (empty($sms_package_info)) {
                    model('sys_order')->rollback();
                    return error([], '找不到当前短信套餐');//非法的短信套餐
                }
                $data['sms_package_id'] = $sms_package_id;
                $data['sms_num'] = $sms_package_num;
                $data['sms_package_num'] = $sms_package_info['sms_num'];
                $data['sms_package_price'] = $sms_package_info['sms_money'];
                $data['sms_package_name'] = $sms_package_info['sms_name'];
                $data['sms_package_image'] = $sms_package_info['sms_image'];

                $sms_money = $data['sms_package_price'] * $data['sms_num'];
                $order_name = empty($order_name) ? "短信套餐" : $order_name . "-" . "短信套餐";
            }

            //非法订单
            if (empty($order_type)) {
                model('sys_order')->rollback();
                return error('', '无效的订单');
            }

            $data["buyer_uid"] = $buyer_info["buyer_uid"];
            $data["buyer_name"] = $buyer_info["buyer_name"];
            $data["group_money"] = $group_money;//套餐总额

            $data["sms_money"] = $sms_money;//短信总额
            $order_money = $group_money + $sms_money;//订单总价
            $data["order_money"] = $order_money;

            $order_type_name = $this->order_type[$order_type];
            $data["order_type"] = $order_type;//订单类型
            $data["order_type_name"] = $order_type_name;//订单类型名称
            $data['order_name'] = $order_name;
            $order_status = 0;
            $order_status_name = $this->order_status[$order_status];
            $data["order_status"] = $order_status;//订单状态
            $data["order_status_name"] = $order_status_name;//订单状态名称


            $data['pay_type'] = 'ONLINE_PAY';
            $pay_type_list = $this->getPayType();
            $data['pay_type_name'] = $pay_type_list['ONLINE_PAY'];

            $pay_model = new Pay();
            $out_trade_no = $pay_model->createOutTradeNo();//交易流水号
            $data ['out_trade_no'] = $out_trade_no;
            $order_no = $this->createOrderNo();
            $data['order_no'] = $order_no;
            $data['create_time'] = time();
            $order_id = model('sys_order')->add($data);
            $pay_model->addPay(0, $out_trade_no, 'ONLINE_PAY', $order_name, $order_name, $data["order_money"], '', 'SysOrderPayNotify', '');

            //todo  生成待支付订单关闭事件
            $this->addOrderCronClose($order_id);
            model('sys_order')->commit();
            return $this->success($out_trade_no);
        } catch (\Exception $e) {
            model('sys_order')->rollback();
            return $this->error(-1, $e->getMessage() . $e->getLine());
        }
    }


    /**
     * 生成订单编号
     *
     * @param array $site_id
     */
    private function createOrderNo()
    {
        $time_str = date('YmdHi');
        $max_no = Cache::get('sys' . "_" . $time_str);
        if (!isset($max_no) || empty($max_no)) {
            $max_no = 1;
        } else {
            $max_no = $max_no + 1;
        }
        $order_no = $time_str . sprintf("%04d", $max_no);
        Cache::set('sys' . "_" . $time_str, $max_no);
        return $order_no;
    }

    /**
     * 订单线上支付
     * @param unknown $out_trade_no
     */
    public function orderOnlinePay($data)
    {
        model('sys_order')->startTrans();
        try {
            $out_trade_no = $data['out_trade_no'];
            $order_info = model('sys_order')->getInfo([['out_trade_no', '=', $out_trade_no]], '*');
            if ($order_info['pay_status'] == 1) {
                return $this->success();
            }
            $this->orderPay($order_info, $data['pay_type']);

            model('sys_order')->commit();
            return $this->success();
        } catch (\Exception $e) {
            model('sys_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }

    /**
     * 修改订单状态
     * @param $order_info
     * @param $pay_type
     * @return array
     */
    public function orderPay($order_info, $pay_type)
    {
        model('sys_order')->startTrans();
        try {
            $pay_type_list = $this->getPayType();
            if ($order_info['pay_status'] != 0) {
                return $this->error();
            }
            $condition = array(
                ['order_id', '=', $order_info['order_id']],
                ['pay_status', '=', 0],
            );

            $data = array(
                'pay_status' => 1,
                'pay_time' => time(),
                'pay_type' => $pay_type,
                'pay_type_name' => $pay_type_list[$pay_type],
                'order_status' => 1,
                'order_status_name' => $this->order_status[1],
            );
            model('sys_order')->update($data, $condition);

            //套餐订单
            if($order_info['order_type'] == 'group'){
                $site_group_model = new SiteGroup();
                $site_group_result = $site_group_model->orderSuccess($order_info);
                if($site_group_result['code'] < 0){
                    model('sys_order')->rollback();
                    return $site_group_result;
                }
            }

            //短信套餐
            if($order_info['order_type'] == 'sms'){
                //给用户添加短信数量
                $sms_num = $order_info['sms_num'] * $order_info['sms_package_num'];
                model('site')->setInc([ ['site_id','=',$order_info['site_id']] ],'sms_num',$sms_num);
            }

            model('sys_order')->commit();
            return $this->success();
        } catch (\Exception $e) {
            model('sys_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }

    /**
     * 提交线下支付
     * @param array $condition
     * @param $data
     * @return array
     */
    public function applyOfflinePay($condition = [], $data)
    {
        $pay_status = model('sys_order')->getInfo($condition);
        if (empty($pay_status)) {
            return $this->error(-1, '找不到可支付的单据');
        }
        $pay_type_list = $this->getPayType();
        $data['order_status'] = 2;
        $data['pay_time'] = time();
        $data['order_status_name'] = $this->order_status[2];
        $data['pay_type'] = 'OFFLINE_PAY';
        $data['pay_type_name'] = $pay_type_list['OFFLINE_PAY'];
        $res = model('sys_order')->update($data,$condition);
        return $this->success($res);
    }

    /**
     * 订单关闭
     * @param $order_id
     */
    public function orderClose($condition){
        model('sys_order')->startTrans();
        try {
            $data = [
                'order_status' => -1,
                'order_status_name' => $this->order_status[-1]
            ];
            //关闭订单状态
            $result = model('sys_order')->update($data, $condition);
//            $order_list = model('sys_order')->getList($condition, 'out_trade_no');
//            $out_trade_nos = array_column($order_list, 'out_trade_no');
//            $out_trade_no_list = array_unique($out_trade_nos);
            //关闭支付
            $pay_model = new Pay();
//            foreach($out_trade_no_list as $k => $v){
//                $close_pay_result = $pay_model->deletePay($v);
//                if($close_pay_result['code'] < 0){
//                    model('sys_order')->rollback();
//                    return $close_pay_result;
//                }
//            }

            model('sys_order')->commit();
            return $this->success();
        } catch (\Exception $e) {
            model('sys_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }


    /**
     * 订单删除
     * @param $order_id
     */
    public function orderDelete($condition){
        model('sys_order')->startTrans();
        try {
            $data = [
                'is_delete' => 1,
            ];
            //关闭订单状态
            $result = model('sys_order')->update($data, $condition);
            model('sys_order')->commit();
            if($result === false){
                return $this->error($result);
            }
            return $this->success($result);
        } catch (\Exception $e) {
            model('sys_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }
    /**
     * 线下支付审核通过
     */
    public function offlinePay($order_id)
    {
        $order_info = model('sys_order')->getInfo([['order_id', '=', $order_id], ['pay_status', '=', 0]]);
        if (empty($order_info)) {
            return $this->error(-1, '参数错误');
        }
        $res = $this->orderPay($order_info, 'OFFLINE_PAY');
        return $res;

    }

    /**
     * 线下支付审核拒绝
     * @param $order_id
     * @return array
     */
    public function refuseOfflinePay($order_id)
    {
        $order_info = model('sys_order')->getInfo([['order_id', '=', $order_id], ['pay_status', '=', 0]]);
        if (empty($order_info)) {
            return $this->error(-1, '参数错误');
        }

        $data = ['order_status' => 3,'order_status_name'=>$this->order_status[3]];
        $res = model('sys_order')->update($data,[['order_id', '=', $order_id], ['pay_status', '=', 0]]);
        return $this->success($res);
    }

    /**
     * 订单详情
     * @param $out_trade_no
     */
    public function getOrderInfo($condition, $field = "*")
    {
        $info = model('sys_order')->getInfo($condition, $field);
        return $this->success($info);
    }

    /**
     * 订单详情
     * @param $out_trade_no
     */
    public function getOrderDetail($out_trade_no)
    {
        $info = model('sys_order')->getInfo([['out_trade_no', '=', $out_trade_no]]);
        return $this->success($info);
    }
    /*********************************************************订单统计*************************************************************/



    /**
     * 增加订单自动关闭事件
     * @param $order_id
     */
    public function addOrderCronClose($order_id)
    {
        //计算订单自动关闭时间
        $now_time = time();
        $execute_time = $now_time + 3600;//尚未配置  默认一小时

        $cron_model = new Cron();
        $cron_model->addCron(1, 0, "订单自动关闭", "CronSysOrderClose", $execute_time, $order_id);
    }
}